home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb.new / gdb-4.0 / gdb / solib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-24  |  10.2 KB  |  367 lines

  1. /* Copyright (C) 1990 Free Software Foundation, Inc.
  2.  
  3. This file is part of GDB.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /*
  20. **    symbol definitions
  21. */
  22. #include <sys/types.h>
  23. #include <string.h>
  24. #include <link.h>
  25. #include <sys/param.h>
  26. #include <fcntl.h>
  27. #include <stdio.h>
  28. #include "defs.h"
  29. #include "param.h"
  30. #include "symtab.h"
  31. #include "gdbcore.h"
  32. #include "command.h"
  33. #include "target.h"
  34. #include "frame.h"
  35. #include "regex.h"
  36.  
  37. extern char *getenv();
  38.  
  39. /*
  40. **    local data declarations
  41. */
  42. #define MAX_PATH_SIZE 256
  43. struct so_list {
  44.     struct link_map inferior_lm;        /* inferior link map */
  45.     struct link_map *inferior_lm_add;
  46.     long   ld_text;
  47.     char inferior_so_name[MAX_PATH_SIZE];    /* Shared Object Library Name */
  48.     struct so_list *next;            /* Next Structure */
  49.     int    symbols_loaded;
  50.     bfd *so_bfd;
  51.     struct section_table *sections;
  52.     struct section_table *sections_end;
  53. };
  54.  
  55. static struct so_list *so_list_head = 0;
  56.  
  57. /*
  58. ** Build a section map for a shared library, record its text size in
  59. ** the so_list structure and set up the text section of the shared lib.
  60. */
  61. static void
  62. solib_map_sections(so)
  63. struct so_list *so;
  64. {
  65.   char *filename;
  66.   char *scratch_pathname;
  67.   int scratch_chan;
  68.   struct section_table *p;
  69.   
  70.   filename = tilde_expand (so->inferior_so_name);
  71.   make_cleanup (free, filename);
  72.   
  73.   scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
  74.                 &scratch_pathname);
  75.   if (scratch_chan < 0)
  76.     scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename, O_RDONLY, 0,
  77.                 &scratch_pathname);
  78.   if (scratch_chan < 0)
  79.     perror_with_name (filename);
  80.  
  81.   so->so_bfd = bfd_fdopenr (scratch_pathname, NULL, scratch_chan);
  82.   if (!so->so_bfd)
  83.     error ("Could not open `%s' as an executable file: %s",
  84.        scratch_pathname, bfd_errmsg (bfd_error));
  85.   if (!bfd_check_format (so->so_bfd, bfd_object))
  86.     error ("\"%s\": not in executable format: %s.",
  87.        scratch_pathname, bfd_errmsg (bfd_error));
  88.   if (build_section_table (so->so_bfd, &so->sections, &so->sections_end))
  89.     error ("Can't find the file sections in `%s': %s", 
  90.        exec_bfd->filename, bfd_errmsg (bfd_error));
  91.  
  92.   for (p = so->sections; p < so->sections_end; p++)
  93.     {
  94.       if (strcmp (bfd_section_name (so->so_bfd, p->sec_ptr), ".text") == 0)
  95.     {
  96.       /* Determine length of text section and relocate it. */
  97.       so->ld_text = p->endaddr - p->addr;
  98.       p->addr += (CORE_ADDR)so->inferior_lm.lm_addr;
  99.       p->endaddr += (CORE_ADDR)so->inferior_lm.lm_addr;
  100.     }
  101.       else
  102.     /* All other sections are ignored for now. */
  103.     p->addr = p->endaddr = 0;
  104.     }
  105. }
  106.  
  107. /*=======================================================================*/
  108.  
  109. /*    find_solib
  110. **
  111. **Description:
  112. **
  113. **    This module contains the routine which finds the names of any loaded
  114. **    "images" in the current process. The argument in must be NULL on the
  115. **    first call, and then the returned value must be passed in on
  116. **    subsequent calls. This provides the capability to "step" down the
  117. **    list of loaded objects. On the last object, a NULL value is returned.
  118. **    The arg and return value are "struct link_map" pointers, as defined
  119. **    in <link.h>.
  120. **
  121. **    NOTE: This only works under SunOS4.0.
  122. */
  123.  
  124. struct so_list *find_solib(so_list_ptr)
  125. struct so_list *so_list_ptr;            /* so_list_head position ptr */
  126. {
  127. struct so_list *so_list_next = 0;
  128. CORE_ADDR inferior_dynamic_ptr = 0;
  129. struct link_map *inferior_lm = 0;
  130. struct link_dynamic inferior_dynamic_cpy;
  131. struct link_dynamic_2 inferior_ld_2_cpy;
  132. struct so_list *new;
  133. int i;
  134.  
  135.      if (!so_list_ptr) {
  136.      if (!(so_list_next = so_list_head)) {
  137.          for (i = 0; i < misc_function_count; i++) {
  138.          if (!strcmp (misc_function_vector[i].name, "_DYNAMIC")) {
  139.              inferior_dynamic_ptr = misc_function_vector[i].address;
  140.              break;
  141.          }    
  142.          }        
  143.          if (inferior_dynamic_ptr) {
  144.          read_memory(inferior_dynamic_ptr, &inferior_dynamic_cpy, sizeof(struct link_dynamic));
  145.          if (inferior_dynamic_cpy.ld_version == 3) {
  146.              read_memory((CORE_ADDR)inferior_dynamic_cpy.ld_un.ld_2,
  147.                  &inferior_ld_2_cpy,
  148.                  sizeof(struct link_dynamic_2));
  149.              inferior_lm = inferior_ld_2_cpy.ld_loaded;
  150.          }
  151.          }
  152.      }
  153.      } else {
  154.      /*
  155.      ** Advance to next local abbreviated load_map structure
  156.      */
  157.      if (!(inferior_lm = so_list_ptr->inferior_lm.lm_next)) {
  158.          /* See if any were added, but be quiet if we can't read
  159.         from the target any more.  */
  160.          int status;
  161.  
  162.          status = target_read_memory (
  163.             (CORE_ADDR)so_list_ptr->inferior_lm_add,
  164.             (char *)&so_list_ptr->inferior_lm,
  165.             sizeof(struct link_map));
  166.          if (status == 0)
  167.            inferior_lm = so_list_ptr->inferior_lm.lm_next;
  168.          else
  169.            inferior_lm = 0;
  170.      }
  171.      so_list_next = so_list_ptr->next;
  172.      }
  173.      if ((!so_list_next) && inferior_lm) {
  174.      /* 
  175.      ** Get Next LM Structure from inferior image and build
  176.      ** an local abbreviated load_map structure
  177.      */
  178.      new = (struct so_list *) xmalloc(sizeof(struct so_list));
  179.          new->inferior_lm_add = inferior_lm;
  180.      read_memory((CORE_ADDR)inferior_lm,
  181.              &new->inferior_lm,
  182.              sizeof(struct link_map));
  183.  
  184.      read_memory((CORE_ADDR)new->inferior_lm.lm_name,
  185.              new->inferior_so_name,
  186.              MAX_PATH_SIZE - 1);
  187.      new->inferior_so_name[MAX_PATH_SIZE - 1] = 0;
  188.      /* Zero everything after the first terminating null */
  189.      strncpy(new->inferior_so_name, new->inferior_so_name, MAX_PATH_SIZE);
  190.  
  191. #if 0
  192.      /* This doesn't work for core files, so instead get ld_text
  193.         using solib_map_sections (below).  */
  194.      read_memory((CORE_ADDR)new->inferior_lm.lm_ld,
  195.              &inferior_dynamic_cpy,
  196.              sizeof(struct link_dynamic));
  197.      read_memory((CORE_ADDR)inferior_dynamic_cpy.ld_un.ld_2,
  198.              &inferior_ld_2_cpy,
  199.              sizeof(struct link_dynamic_2));
  200.      new->ld_text = inferior_ld_2_cpy.ld_text;
  201. #endif
  202.  
  203.      new->next = 0;
  204.      new->symbols_loaded = 0;
  205.      new->so_bfd = NULL;
  206.      new->sections = NULL;
  207.      if (so_list_ptr)
  208.          so_list_ptr->next = new;
  209.      else
  210.          so_list_head = new;
  211.  
  212.      solib_map_sections (new);
  213.  
  214.      so_list_next = new;
  215.      }
  216.      return(so_list_next);
  217. }
  218.  
  219.  
  220. void
  221. solib_add (arg_string, from_tty, target)
  222.      char *arg_string;
  223.      int from_tty;
  224.      struct target_ops *target;
  225. {    
  226.   register struct so_list *so = 0;       /* link map state variable */
  227.   char *val;
  228.   int count, old;
  229.   struct section_table *sec;
  230.  
  231.   if (arg_string == 0)
  232.       re_comp (".");
  233.   else if (val = (char *) re_comp (arg_string)) {
  234.       error ("Invalid regexp: %s", val);
  235.   }
  236.  
  237.   /* Getting new symbols may change our opinion about what is
  238.      frameless.  */
  239.   reinit_frame_cache ();
  240.  
  241.   printf_filtered ("Shared libraries");
  242.   if (arg_string)
  243.     printf_filtered (" matching regular expresion \"%s\"", arg_string);
  244.   printf_filtered (":\n");
  245.   
  246.   dont_repeat();
  247.  
  248.   while (so = find_solib(so)) {
  249.       if (re_exec(so->inferior_so_name)) {
  250.       if (so->symbols_loaded) {
  251.           printf("Symbols already loaded for %s\n", so->inferior_so_name);
  252.       } else {
  253.           symbol_file_add (so->inferior_so_name, from_tty,
  254.                    (unsigned int)so->inferior_lm.lm_addr, 0);
  255.           so->symbols_loaded = 1;
  256.       }
  257.       }
  258.   }
  259.  
  260.   /* Now add the shared library sections to the section table of the
  261.      specified target, if any.  */
  262.   if (target) {
  263.     /* Count how many new section_table entries there are.  */
  264.     so = 0;
  265.     count = 0;
  266.     while (0 != (so = find_solib (so))) {
  267.       count += so->sections_end - so->sections;
  268.     }
  269.  
  270.     if (count) {
  271.       /* Reallocate the target's section table including the new size.  */
  272.       if (target->sections) {
  273.     old = target->sections_end - target->sections;
  274.     target->sections = (struct section_table *)
  275.         realloc ((char *)target->sections,
  276.           (sizeof (struct section_table)) * (count + old));
  277.       } else {
  278.     old = 0;
  279.     target->sections = (struct section_table *)
  280.         malloc ((sizeof (struct section_table)) * count);
  281.       }
  282.       target->sections_end = target->sections + (count + old);
  283.  
  284.       /* Add these section table entries to the target's table.  */
  285.       while (0 != (so = find_solib (so))) {
  286.     count = so->sections_end - so->sections;
  287.     bcopy (so->sections, (char *)(target->sections + old), 
  288.            (sizeof (struct section_table)) * count);
  289.     old += count;
  290.       }
  291.     }
  292.   }
  293. }
  294.  
  295. /*=======================================================================*/
  296.  
  297. static void solib_info()
  298. {
  299. register struct so_list *so = 0;      /* link map state variable */
  300.  
  301.     while (so = find_solib(so)) {
  302.     if (so == so_list_head) {
  303.         printf("      Address Range      Symbols     Shared Object Library\n");
  304.     }
  305.     printf(" 0x%08x - 0x%08x   %s   %s\n", 
  306.         so->inferior_lm.lm_addr, 
  307.         so->inferior_lm.lm_addr + so->ld_text - 1,
  308.         (so->symbols_loaded ? "Yes" : "No "),
  309.         so->inferior_so_name);
  310.     }
  311.     if (!so_list_head) {
  312.     printf("No shared libraries loaded at this time.\n");    
  313.     }
  314. }
  315.  
  316. /*
  317. ** Called by Insert Breakpoint to see if Address is Shared Library Address 
  318. */
  319. int
  320. solib_address(address)
  321.      CORE_ADDR address;
  322. {
  323. register struct so_list *so = 0;       /* link map state variable */
  324.  
  325.     while (so = find_solib(so)) {
  326.     if ((address >= (CORE_ADDR) so->inferior_lm.lm_addr) &&
  327.         (address < (CORE_ADDR) so->inferior_lm.lm_addr + so->ld_text))
  328.       return 1;
  329.     }
  330.     return 0;
  331. }
  332.  
  333. /*
  334. ** Called by free_all_symtabs
  335. */
  336. void 
  337. clear_solib()
  338. {
  339. struct so_list *next;
  340.  
  341.   while (so_list_head) {
  342.     if (so_list_head->sections)
  343.       free (so_list_head->sections);
  344.     if (so_list_head->so_bfd)
  345.       bfd_close (so_list_head->so_bfd);
  346.     next = so_list_head->next;
  347.     free(so_list_head);
  348.     so_list_head = next;
  349.   }
  350. }
  351.  
  352. void
  353. sharedlibrary_command (args, from_tty)
  354. {
  355.   solib_add (args, from_tty, (struct target_ops *)0);
  356. }
  357.  
  358. void
  359. _initialize_solib()
  360. {
  361.  
  362.   add_com("sharedlibrary", class_files, sharedlibrary_command,
  363.        "Load shared object library symbols for files matching REGEXP.");
  364.   add_info("sharedlibrary", solib_info, 
  365.        "Status of loaded shared object libraries");
  366. }
  367.